package org.hk.kg.web;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hk.kg.TraceObject;
import org.hk.kg.exception.EleParserException;
import org.hk.kg.ui.IHTMLDisplayer;
import org.hk.kg.ui.KGUiContext;
import org.hk.kg.ui.ParamsStack;
import org.hk.kg.utils.Constants;
import org.hk.kg.utils.LocalResouce;
import org.hk.kg.utils.StringUtils;

interface Action {
	public void request();
	public void request(Map map);

	public String execute();

	public void init();

	public String invoke(String method) throws EleParserException;

	public Object invoke(String methodName, ParamsStack stack)
			throws EleParserException;
}

public class BaseAction implements Action {
	protected static Log logger = LogFactory.getLog(BaseAction.class);
	protected IHTMLDisplayer displayer;
	private Map params = new HashMap();
	protected String id;
	protected String packageName;
	public static final String None = "none";

	private final void initailize() {
		if (params != null) {
			params.clear();
		}
		else{
			params = new HashMap();
		}
		init();
	}
	
	private void writeToFile(String rlt)
	{
		BufferedReader reader = null;
		BufferedWriter writer = null;
		try {
			File tempDir = new File(Constants.PAGES_TEMP_ROOT);
			if (!tempDir.exists() || !tempDir.isDirectory()) {
				tempDir.mkdir();
			}
			File tempFile = File.createTempFile(Constants.PAGES_TEMP_ROOT,
					("" + System.currentTimeMillis()).concat(".html"));
			tempFile.deleteOnExit();

			InputStream ips = LocalResouce.getHtmlFile(rlt);
			reader = new BufferedReader(new InputStreamReader(ips));
			writer = new BufferedWriter(new FileWriter(tempFile));

			String line = null;
			while ((line = reader.readLine()) != null) {
				writer.write(HtmlRenderUtils.instance.render(line, this));
			}
			this.displayer.display(tempFile.toURI().toURL(),this);
		} catch (IOException e) {
			logger.error(e);
		} catch(Exception e){
			e.printStackTrace();
		}finally {
			try {
				reader.close();
				writer.close();
			} catch (IOException e) {
				logger.warn("failed to close buffered", e);
			}
		}
	}
	
	private void writeToTarget(String rlt)
	{
		BufferedReader reader = null;
		StringBuffer buffer = new StringBuffer();
		try {
			InputStream ips = LocalResouce.getHtmlFile(rlt);
			reader = new BufferedReader(new InputStreamReader(ips));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(HtmlRenderUtils.instance.render(line, this));
			}
		}catch (IOException e) {
			logger.error(e);
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				logger.warn("failed to close buffered", e);
			}
		}
		
		this.displayer.display(buffer.toString(),
				params.get(Constants.UI_SYS_TARGET_KEY).toString(),
				this);
	}
	
	public final void request()
	{
		this.request(new HashMap());
	}
	public final void request(Map map) {
		initailize();
		String rlt = execute();
		if(null != map)
		{
			this.params.putAll(map);
		}
		if (!StringUtils.isEmpty(rlt)) {
			if(this.params.containsKey(Constants.UI_SYS_TARGET_KEY))
			{
				writeToTarget(rlt);
			}
			else
			{
				writeToFile(rlt);
			}
		}
	}

	public final void setDisplayer(IHTMLDisplayer displayer) {
		this.displayer = displayer;
	}

	public final void setId(String id) {
		this.id = id;
	}

	public final Map getParams() {
		if (params == null) {
			params = new HashMap();
		}
		return params;
	}

	public final void setParams(Map params) {
		this.params = params;
	}
	

	public final void setPackage(String packageName) {
		this.packageName = packageName;
	}
	public final String invoke(String methodName) throws EleParserException {
		String rlt = null;
		try {
			Method method = this.getClass().getMethod(methodName);
			rlt = (String) method.invoke(this);
		} catch (Exception e) {
			logger.error(e);
			throw new EleParserException();
		}
		return rlt;
	}

	public final Object invoke(String methodName, ParamsStack stack)
			throws EleParserException {
		Object rlt = null;
		try {
			Method method = this.getClass().getMethod(methodName,
					ParamsStack.class);
			rlt = method.invoke(this, stack);
		} catch (Exception e) {
			logger.error(e);
			//TODO : exception 
			throw new EleParserException();
		}
		return rlt;
	}

	public String execute() {
		if(!StringUtils.isEmpty(packageName))
		{
			return this.packageName + "/" + this.id;
		}
		else
		{
			return this.id;
		}
	}

	public void init() {
	}

	/**
	 * 通用方法,后退到上一页面
	 * 
	 * @param params
	 * @return
	 */
	public final TraceObject back(ParamsStack params) {
		return KGUiContext.instance.action_backward();
	}
	
	/**
	 * 将当前页内容转换为需打印的HTML页并展示
	 */
	public final void prevHtml(ParamsStack params)
	{
		
	}
}
